import cv2
import numpy as np
from PIL import Image
from . import JTool as jt
#---色彩空间类方法


def pathImg2cv2(path_img):
    """_summary__(摘要信息):用cv2读取图片

    Args(参数集):
        img_path (图片路径): _description_(描述)接收一个图片路径

    Returns(返回集):
        _type_(返回类型): _description_(描述)返回一个cv2图片也是np数组
    """

    # 实际上，当你使用 cv2.imread 读取图像时，OpenCV 会将图像数据以 NumPy 数组的形式返回。因此，你直接得到的就是一个 NumPy 数组。
    # 读取图片
    img = cv2.imread(path_img)
    # 返回np数组,也是cv2图片
    return img

def array2np(img_array):
    """_summary_(摘要信息):将cv2图片转为np数组

    Args(参数集):            
        img_array (cv2图片): _description_(描述)接收一个cv2图片

    Returns(返回集):
        _type_(返回类型): _description_(描述)返回一个np数组
    """
    # 转换为np数组
    img_np = np.array(img_array)
    # 返回np数组
    return img_np

def cv22np(img_cv2):
    """_summary_(摘要信息):将cv2图片转为np数组(默认这一方法是多余的,因为cv2就是np数组)

    Args(参数集):            
        img_cv2 (cv2图片): _description_(描述)接收一个cv2图片

    Returns(返回集):            
        _type_(返回类型): _description_(描述)返回一个np数组
    """
    # 转换为np数组
    img_np = np.array(img_cv2)
    # 返回np数组
    return img_np


def pathImg2PIL(path_img):
    """_summary_(摘要信息):用PIL读取图片

    Args(参数集):
        img_path (图片路径): _description_(描述)接收一个图片路径

    Returns(返回集):
        _type_(返回类型): _description_(描述)返回一个PIL图片
    """
    # 读取图片
    img = Image.open(path_img)
    # 返回PIL图片Image对象
    return img

def PIL2cv2(img_PIL):
    """_summary_(摘要信息):将PIL图片转为cv2图片

    Args(参数集):                
        img_PIL (PIL图片): _description_(描述)接收一个PIL图片

    Returns(返回集):                
        _type_(返回类型): _description_(描述)返回一个cv2图片
    """
    # 转换为cv2图片
    img_cv2 = cv2.cvtColor(np.array(img_PIL), cv2.COLOR_RGB2BGR)
    # 返回cv2图片
    return img_cv2

def cv22PIL(img_cv2):
    """_summary_(摘要信息):将cv2图片转为PIL图片

    Args(参数集):                
        img_cv2 (cv2图片): _description_(描述)接收一个cv2图片

    Returns(返回集):                
        _type_(返回类型): _description_(描述)返回一个PIL图片
    """
    # 转换为PIL图片
    img_PIL = Image.fromarray(cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB))
    # 返回PIL图片
    return img_PIL

def pathImg2LPIL(path_img):
    """_summary_(摘要信息):用LPIL读取图片,并转换为L模式(单通道)返回

    Args(参数集):
        img_path (图片路径): _description_(描述)接收一个图片路径

    Returns(返回集):
        _type_(返回类型): _description_(描述)返回一个LPIL图片
    """
    # 读取图片
    img = Image.open(path_img).convert("L")
    # 返回LPIL图片
    return img

def getImgPILMode(img_PIL):
    """_summary_(摘要信息):获取PIL图片的模式

    Args(参数集):
        img_PIL (PIL图片): _description_(描述)接收一个PIL图片

    Returns(返回集):            
        _type_(返回类型): _description_(描述)返回一个字符串,表示图片的模式
    """
    # 获取图片的模式
    mode = img_PIL.mode
    # 返回图片的模式(RGB,L,RGBA,CMYK等)
    return mode

def getImgCV2Mode(img_cv2):
    """获取cv2图片的模式

    Args:
        img_cv2 (cv2图片): 接收一个cv2图片

    Returns:
        str: 返回一个字符串,表示图片的模式
    """
    # 获取图片的形状
    height, width, channels = img_cv2.shape

    # 根据通道数量推断颜色模式
    if channels == 3:
        # 默认OpenCV的3通道图像是BGR
        return "BGR"
    elif channels == 4:
        # 默认OpenCV的4通道图像是BGRA
        return "BGRA"
    elif channels == 1:
        # 单通道图像是灰度图像
        return "L"
    else:
        return "未知模式"

def getImgcv2Dtype(img_cv2):
    """_summary_(摘要信息):获取cv2图片的dtype:返回图像像素的数据类型，例如 uint8、float32 等。

    Args(参数集):            
        img_cv2 (cv2图片): _description_(描述)接收一个cv2图片                

    Returns(返回集):            
        _type_(返回类型): _description_(描述)返回一个字符串,表示图片的dtype:例如 uint8、float32 等。
    """
    # 获取图片的dtype
    dtype = img_cv2.dtype
    # 返回图片的dtype
    return dtype
    

# 将图片从BGR转换到HSV颜色空间
def cvt2HSV(img):
    # 将图片从BGR转换到HSV颜色空间
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    return hsv
#  将图片从BGR转换到RGB颜色空间
def cvtBGR2RGB(img):
    rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    return rgb

#  将图片从RGB转换到RGB颜色空间
def cvtRGB2BGR(img):
    bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    return bgr

#  将图片从BGR转换到GRAY(灰度图,单通道)
def cvtBGR2GRAY(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return gray


#---图像处理类方法
def ps_new0(nWidth,nHeight,change,dtype=np.uint8):
    #创建一个新的图纸
    return np.zeros(( nWidth,nHeight, change), dtype)

def ps_sd_fxyi(img,ffx=5,ffy=5):
    # 放大图片,默认5倍
    return cv2.resize(img,(0,0),fx=ffx,fy=ffy,interpolation=cv2.INTER_NEAREST)

def ps_sele_color(img,colors=(139,140,175),mixc=20,maxc=20):
    # 选取图像颜色范围,返回单通道
    color_mixc=[i-mixc for i in colors]
    color_maxc=[i+maxc for i in colors]
    # 颜色点转(BGR),方便CV2使用
    color_mixc=jt.rgb2bgr(color_mixc)
    color_maxc=jt.rgb2bgr(color_maxc)
    # 定义小于通道和大于通道值归0区间
    lower_blue = np.array(color_mixc)
    upper_blue = np.array(color_maxc)
    mask_blue = cv2.inRange(img, lower_blue, upper_blue)
    return mask_blue
    


def ps_dilate_ones(img,ones3=(5,5),iterations=2):
    # 膨胀图片,维度核(必须是奇数倍)默认=(5,5),腐蚀次数=2
    # 定义维度核
    np_noes=np.ones(ones3,dtype=np.uint8)
    # cv2的腐蚀函数
    img=cv2.dilate(img,np_noes,iterations)
    # 返回腐蚀图像
    return img

def ps_erode_ones(img,ones3=(5,5),iterations=2):
    # 腐蚀图片,维度核(必须是奇数倍)默认=(5,5),腐蚀次数=2
    # 定义维度核
    np_noes=np.ones(ones3,dtype=np.uint8)
    # cv2的腐蚀函数
    img=cv2.erode(img,np_noes,iterations)
    # 返回腐蚀图像
    return img

def ps_morphologyEx_ones(img,morph=cv2.MORPH_OPEN,ones3=(5,5),iterations=2):
    # 开闭运算图片,开闭模式=[cv2.MORPH_OPEN,cv2.MORPH_CLOSE]
    # 维度核(必须是奇数倍)默认=(5,5),开闭次数=2
    # 定义维度核
    np_noes=np.ones(ones3,dtype=np.uint8)
    # cv2的开闭函数
    img=cv2.morphologyEx(img,op=morph,kernel=np_noes,iterations=iterations)
    # 返回图像
    return img

# ps修图-色阶(传入cv2图,阴影,中间调,高光)
# 中间调取 0 -50- 100(代表不改变)
# 阴影高光值取0-255
def white_black_level_pretreatment(
    img, shadow, midtone, highlight, output_shadow=None, output_highlight=None
):
    if highlight > 255:
        highlight = 255
    if shadow < 0:
        shadow = 0
    if shadow >= highlight:
        shadow = highlight - 2

    img = np.array(img, dtype=float)  # 确保使用浮点数进行计算

    diff = highlight - shadow
    coe = 255.0 / diff

    # 计算调整后的图像
    rgb_diff = img - shadow
    rgb_diff = np.maximum(rgb_diff, 0)
    adjusted_img = rgb_diff * coe

    # 应用伽马校正来调整中间调
    gamma = midtone / 100.0
    adjusted_img = np.power(adjusted_img, gamma)

    # 调整阴影和高光输出
    if output_shadow is not None:
        adjusted_img = np.clip(adjusted_img + (output_shadow - shadow), 0, 255)
    if output_highlight is not None:
        adjusted_img = np.clip(adjusted_img - (highlight - output_highlight), 0, 255)

    # 确保值在0到255之间，并转换为8位无符号整数
    adjusted_img = np.clip(adjusted_img, 0, 255)
    adjusted_img = adjusted_img.astype(np.uint8)

    return adjusted_img











#---视频类方法

def getFrameCur(cap):
    # 获取当前帧数
    current_frame = cap.get(cv2.CAP_PROP_POS_FRAMES)
    return current_frame

def getFrameCount(cap):
    # 获取视频的总帧数
    total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
    
def getFrameFPS(cap):
    # 获取视频的帧率
    fps = cap.get(cv2.CAP_PROP_FPS)
    return fps
